package com.express.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.express.common.result.*;
import com.express.constants.Constants;
import com.express.core.mapper.OrdersMapper;
import com.express.dto.*;
import com.express.emnus.GOODSTYPE;
import com.express.entity.Address;
import com.express.entity.RoutingInfos;
import com.express.entity.UserOrders;
import com.express.entity.UserReceipt;
import com.express.service.IAddressService;
import com.express.service.IOrderService;
import com.express.sys.mapper.RoutingInfosMapper;
import com.express.sys.mapper.UserRectiptMapper;
import com.express.util.DateUtils;
import com.express.util.SignUtils;
import com.express.vo.OrderReceiptVo;
import com.google.gson.Gson;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements IOrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Value("${kuaidi100.orderUrl}")
    private String orderUrl;
    @Value("${kuaidi100.queryUrl}")
    private String queryUrl;
    @Autowired
    OrdersMapper mapper;
    @Autowired
    UserRectiptMapper userRectiptMapper;
    @Autowired
    IAddressService addressService;
    // 记录通知后台的订单信息
    Map<String, Object> newOrderMap = new HashMap<>();

    @Autowired
    RoutingInfosMapper routingInfosMapper;
    @Autowired
    private OrdersMapper ordersMapper;

    @Override
    public int save(UserOrders orders) {
        return mapper.save(orders);
    }

    @Override
    public Map getTotal(Map map) throws Exception {
        return mapper.getTotal(map);
    }

    @Override
    public List<UserOrders> getList(Map map) {
        return mapper.getList(map);
    }

    @Override
    public UserOrders getOrder(Integer id) {
        return mapper.getOrder(id);
    }

    @Override
    public UserOrders getOrderByOrderNo(String orderNo) {
        return mapper.getOrderByOrderNo(orderNo);
    }

    @Override
    public UserOrders getOrderByAppointNo(String appointNo) {
        return mapper.getOrderByAppointNo(appointNo);
    }

    @Override
    public int update(UserOrders order) {
        return mapper.update(order);
    }

    @Override
    public void loadNewOrder(String count) {
        this.newOrderMap.put("notify", count);
    }

    @Override
    public List<UserOrders> getOrderByIds(int[] ids) {
        return mapper.getOrderByIds(ids);
    }

    @Override
    public String getNewOrder() {
        String msg = "";
        if (newOrderMap.containsKey("notify")) {
            msg = this.newOrderMap.get("notify").toString();
            this.newOrderMap.clear();
        }
        return msg;
    }

    @Override
    public Result<Kauidi100OrderResultVO> doOrder(UserOrders orders) {
        try {
            OrderKuaidi100ManInfo recManInfo = new OrderKuaidi100ManInfo();
            String receiveId = orders.getReceiveId();
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("type", 1);
            paramMap.put("id", receiveId);
            List<Address> list = addressService.query(paramMap);
            if (null != list && list.size() > 0) {
                Address address = list.get(0);
                recManInfo.setName(address.getName());
                recManInfo.setMobile(address.getPhone());
                recManInfo.setPrintAddr(address.getAddress());
            }

            OrderKuaidi100ManInfo sendManInfo = new OrderKuaidi100ManInfo();
            sendManInfo.setName(orders.getSendName());
            sendManInfo.setMobile(Constants.EN_PHONE);
//            sendManInfo.setMobile(orders.getSendPhone());
            sendManInfo.setPrintAddr(orders.getSendCompany());

            OrderKuaidi100Req orderKuaidi100Req = new OrderKuaidi100Req();
            orderKuaidi100Req.setKuaidicom("shunfeng");
            orderKuaidi100Req.setCount(1);
            orderKuaidi100Req.setSiid("");
            orderKuaidi100Req.setTempId(Constants.TEMPID);
            orderKuaidi100Req.setSendMan(sendManInfo);
            orderKuaidi100Req.setRecMan(recManInfo);
            orderKuaidi100Req.setPrintType("NON");
            orderKuaidi100Req.setPartnerId("0200149315");
            orderKuaidi100Req.setCargo(GOODSTYPE.valueOf(orders.getGoodsType()));
            orderKuaidi100Req.setPayType("SHIPPER");
            orderKuaidi100Req.setExpType("标准快递");
//            orderKuaidi100Req.setRemark("测试下单,请勿发货");

            orderKuaidi100Req.setOrderId(orders.getOrderNo());
            orderKuaidi100Req.setReorder(false);
            String param = new Gson().toJson(orderKuaidi100Req);

            Long t = System.currentTimeMillis();
            OrderKuaidi100PrintReq printReq = new OrderKuaidi100PrintReq();
            printReq.setT(t + "");
            printReq.setKey(Constants.CODE);
            // 签名 32位大写，签名，用于验证身份，按MD5 (param +t+key+ secret)的顺序进行MD5加密，不需要加上“+”号
//            String sign = MD5Util.md5(param + current + Constants.CODE + Constants.SECRET);
            printReq.setSign(SignUtils.printSign(param, t + "", Constants.CODE, Constants.SECRET));
            printReq.setMethod("order");
            printReq.setParam(param);
            HttpResult httpResult = com.express.utils.HttpUtils.doPost(orderUrl, printReq, 3000, 3000);
            logger.info("请求kuaidi100 url:{}", orderUrl);
            logger.info("参数：{}", JSON.toJSONString(printReq));
            logger.info("返回 ：{}", httpResult.getBody());
            if (httpResult.getStatus() == HttpStatus.SC_OK) {
                // 更新单号
                JSONObject jsonObject = JSON.parseObject(httpResult.getBody());
                orders.setKuaidicom(jsonObject.getString("kuaidinum"));
                mapper.update(orders);
            }
            return JSON.parseObject(httpResult.getBody(), Result.class);
        } catch (Exception e) {
            logger.error("同步订单异常", e);
        }
        return null;
    }

    @Override
    public Result<List<Kauidi100QueryResultDataVo>> queryOrder(Integer orderId, String kuaidinum) {
        UserOrders order = null;
        if (Objects.isNull(kuaidinum) || StringUtils.isEmpty(kuaidinum)) {
//            order = getOrder(orderId);
            return Result.error(201, "查询快递号不能为空");
        }
        try {
            // 查询单号
//            order = getOrderByOrderNo(kuaidinum);
            UserReceipt userReceipt = null;
            Map<String, Object> map = new HashMap<>();
            map.put("oddNumber", kuaidinum);
            List<UserReceipt> userReceipts = userRectiptMapper.queryList(map);
            if (CollectionUtils.isNotEmpty(userReceipts)) {
                userReceipt = userReceipts.get(0);
            } else {
                List<UserOrders> list = ordersMapper.getList(map);
                if (CollectionUtils.isNotEmpty(list)) {
                    order = list.get(0);
                }
            }
            if (ObjectUtil.isNotNull(order) || ObjectUtil.isNotNull(userReceipt)) {
                logger.info("当前订单号: {},快递号为：{}", "", kuaidinum);
                if (StringUtils.isNotEmpty(kuaidinum)) {
                    OrderReceiptVo routData = getRoutData(kuaidinum);
                    if (routData.getReceiptData().getInfosList() != null && routData.getReceiptData().getInfosList().size() > 0) {
                        return Result.ok(initData(routData.getReceiptData().getInfosList(), userReceipt,order));
                    } else {
                        return Result.error(201, "暂无数据");
                    }
//                    return testJsonData(kuaidinum);
//
                }
            } else {
                return testJsonData(kuaidinum);
//                return Result.error(201,"运单号不存在");
            }
            OrderQueryKuaidi100TrackReq queryTrackReq = new OrderQueryKuaidi100TrackReq();
            OrderQueryKuaidi100TrackParmaDto queryTrackParam = new OrderQueryKuaidi100TrackParmaDto();
            queryTrackParam.setCom("shunfeng");
            queryTrackParam.setNum(kuaidinum);
            queryTrackParam.setPhone(Constants.EN_PHONE);
//            queryTrackParam.setPhone(order.getSendPhone());
            String param = new Gson().toJson(queryTrackParam);

            queryTrackReq.setParam(param);
            queryTrackReq.setCustomer(Constants.CUSTOMER);
            queryTrackReq.setSign(SignUtils.querySign(param, Constants.CODE, Constants.CUSTOMER));
            HttpResult httpResult = com.express.utils.HttpUtils.doPost(queryUrl, queryTrackReq, 3000, 3000);
            logger.info("请求kuaidi100 查询url:{}", queryUrl);
            logger.info("参数：{}", JSON.toJSONString(queryTrackReq));
            logger.info("返回 ：{}", httpResult.getBody());
            return JSON.parseObject(httpResult.getBody(), Result.class);
        } catch (Exception e) {
            logger.error("查询订单异常", e);
        }
        return null;
    }

    @Override
    public Kauidi100QueryResultVo queryOrder(Query100OrderDto orderDto) {

        return null;
    }

    @Override
    public Kauidi100OrderResultVO labelOrder(Label100OrderDto orderDto) {

        return null;
    }

    @Override
    public Kauidi100QueryResultVo queryOrderByPhone(Query100ByPhoneOrderDto orderDto) {
        return null;
    }

    @Override
    public OrderReceiptVo qeryOrderReceipt(String orderId) {
        OrderReceiptVo orderReceiptVo = null;
        try {
            if (StringUtils.isEmpty(orderId)) {
                logger.error("orderId 不能为空");
                return null;
            }
            UserOrders order = mapper.getOrder(Integer.valueOf(orderId));
            if (null == order) {
                logger.error("orderId:{} 不存在", orderId);
                return null;
            }
            orderReceiptVo = getRoutData(order.getOrderNo());
        } catch (Exception e) {
            logger.error("查询失败", e);
            throw new RuntimeException(e);
        }
        return orderReceiptVo;
    }

    @Override
    @Transactional
    public boolean updateByAppointNo(UpdateOrderDto orderDto) {
        UserOrders userOrders = getOrderByAppointNo(orderDto.getAppointNo());
        if (Objects.isNull(userOrders)) {
            throw new RuntimeException("查询订单失败");
        }
        if (StringUtils.isNotEmpty(orderDto.getLogisticsNumber())) {
            if (!orderDto.isReplaceFlag()) {
                throw new RuntimeException("物流号已经更新过是否替换新的");
            }
        }
        userOrders.setLogisticsNumber(orderDto.getLogisticsNumber());
        return ordersMapper.update(userOrders) > 0;
    }

    /**
     * 获取路由信息
     *
     * @param oddNumber
     * @return
     */
    private OrderReceiptVo getRoutData(String oddNumber) {
        Map<String, Object> map = new HashMap<>();
        map.put("oddNumber", oddNumber);
        List<UserReceipt> userReceipts = userRectiptMapper.queryList(map);
        OrderReceiptVo orderReceiptVo = new OrderReceiptVo();
        orderReceiptVo.setOrderNo(oddNumber);
        Integer recId = null;
        if (CollectionUtils.isNotEmpty(userReceipts)) {
            recId = userReceipts.get(0).getId();
            orderReceiptVo.setReceiptData(userReceipts.get(0));
        } else {
            List<UserOrders> list = ordersMapper.getList(map);
            if (CollectionUtils.isNotEmpty(list)) {
                recId = list.get(0).getId();
                UserReceipt userReceipt = new UserReceipt();
                BeanUtils.copyProperties(list.get(0), userReceipt);
                orderReceiptVo.setReceiptData(userReceipt);
            }
        }
        // 查询物流
        map.clear();
        map.put("receiptId", recId);
        List<RoutingInfos> routingInfos = routingInfosMapper.queryList(map);
        orderReceiptVo.getReceiptData().setInfosList(routingInfos);
        return orderReceiptVo;
    }

    private void validateParam(Label100OrderDto label100OrderDto, Query100OrderDto query100OrderDto) {
        if (!Objects.isNull(label100OrderDto)) {

        }
        if (!Objects.isNull(query100OrderDto)) {

        }
    }

    /**
     * 初始化快递信息
     *
     * @param routingInfos
     * @return
     */
    private List<Kauidi100QueryResultDataVo> initData(List<RoutingInfos> routingInfos, UserReceipt userReceipt,UserOrders order) {
        List<Kauidi100QueryResultDataVo> vos = new ArrayList<>();
        for (RoutingInfos routingInfo : routingInfos) {
            Kauidi100QueryResultDataVo vo = new Kauidi100QueryResultDataVo();
            vo.setContext(routingInfo.getAddr());
            vo.setTime(DateUtils.matter1.format(routingInfo.getTranTime()));
            vo.setFtime(DateUtils.matter1.format(routingInfo.getTranTime()));
            vo.setLocation("");
            vo.setStatus(routingInfo.getStatus().replace("\\n", ""));
            vo.setWeight(ObjectUtil.isNull(userReceipt) ? order.getWeight().toString() : userReceipt.getWeight());
            vos.add(vo);
        }
        return vos;
    }


    private List<Kauidi100QueryResultDataVo> getTestData(int na1, int na2, int na3, int na4) {
        List<String> staList = Arrays.asList("揽收", "在途", "派件", "签收");
        List<String> nameList = Arrays.asList("梅州", "广州", "郴州", "梅州");
        List<String> areList = Arrays.asList("广东省 广州市 越秀区", "湖南省 郴州市 苏仙区", "广东省 梅州市 梅县区", "广东省 广州市 番禺区");
        Kauidi100QueryResultDataVo vo = new Kauidi100QueryResultDataVo();
        vo.setContext("小哥已取件");
        vo.setTime(DateUtils.getToday());
        vo.setFtime(DateUtils.getToday());
        vo.setAreaName(areList.get(na1).replace(" ", ","));
        vo.setStatus(staList.get(0));
        vo.setLocation(areList.get(na1));

        Kauidi100QueryResultDataVo vo1 = new Kauidi100QueryResultDataVo();
        BeanUtils.copyProperties(vo, vo1);
        vo1.setContext("【" + nameList.get(na2) + "市】快件离开【" + nameList.get(na2) + "转运中心】已发往【" + nameList.get(na3) + "网点】");
        vo1.setStatus(staList.get(1));
        Kauidi100QueryResultDataVo vo2 = new Kauidi100QueryResultDataVo();
        BeanUtils.copyProperties(vo, vo2);
        vo2.setStatus(staList.get(2));
        vo2.setContext("快件到达【" + nameList.get(na3) + "网点】");
        Kauidi100QueryResultDataVo vo3 = new Kauidi100QueryResultDataVo();
        BeanUtils.copyProperties(vo, vo3);
        vo3.setStatus(staList.get(2));
        vo3.setContext("小哥正在派件");
        vo3.setLocation(areList.get(na4));
        vo3.setAreaName(areList.get(na4).replace(" ", ","));

        Kauidi100QueryResultDataVo vo4 = new Kauidi100QueryResultDataVo();
        BeanUtils.copyProperties(vo, vo4);
        vo4.setStatus(staList.get(3));
        vo4.setContext("快件已被代签 您的包裹已存放至【驿站】，记得早点来取它回家");
        vo4.setLocation(areList.get(na4));
        vo4.setAreaName(areList.get(na4).replace(" ", ","));
        List list = new ArrayList();
        list.add(vo);
        list.add(vo1);
        list.add(vo2);
        list.add(vo3);
        list.add(vo4);
        list = (List) list.stream().sorted(Comparator.comparing(Kauidi100QueryResultDataVo::getStatus).reversed())
                .collect(Collectors.toList());
        return list;
    }

    private Result<List<Kauidi100QueryResultDataVo>> testJsonData(String str) {
        logger.info("测试单查询 {}", str);
        String temp = "";
        String temp2 = "";
        String temp3 = "";
        // 测试用
        Kauidi100QueryResultVo resultVo = new Kauidi100QueryResultVo();
        List<String> lit = Arrays.asList("lbt33199", "lbt35277", "lbt32101");
        List<Integer> suList = Arrays.asList(2, 1, 2, 3);
        Collections.shuffle(suList);
        if (lit.contains(str)) {
//            resultVo.setData(getTestData(2,1,2,3));
            resultVo.setData(getTestData(suList.get(0), suList.get(1), suList.get(2), suList.get(3)));
            return Result.ok(resultVo.getData());
        }
        return Result.error(201, "运单号不存在");
    }
}
